import type { Context } from 'elysia';
import { eq, desc, asc, like, and, or, count, sql, inArray } from 'drizzle-orm';
import { db } from '../db';
import { cases, tags, caseCategories } from '../db/schema';
import { nanoid } from 'nanoid';
import { successResponse, paginatedResponse, errorResponse, createPaginationMeta, ApiError, asyncHandler, Logger } from '../utils/response';
import { logUserOperation, logDatabaseOperation } from '../utils/systemLogger';
import type { AuthContext } from '../middleware/auth';
import { checkReadOnlyAccess } from '../middleware/auth';
// 移除INDUSTRIES导入，改为直接定义行业数据
import type { CaseQueryDTO, CaseCreateDTO, CaseUpdateDTO } from '../types/dto';
import { CaseMapper } from '../mappers';

// 获取案例列表
export const getCases = asyncHandler(async ({ query, set }: Context) => {
    const {
      current = '1',
      pageSize = '10',
      category,
      tags: tagIds,
      search,
      featured,
      status = 'published',
      sortBy = 'createdAt',
      sortOrder = 'desc'
    } = query as CaseQueryDTO;

    const pageNum = parseInt(current as string);
    const limitNum = parseInt(pageSize as string);
    const offset = (pageNum - 1) * limitNum;

    // 构建查询条件
    const conditions = [];
    
    if (status) {
      conditions.push(eq(cases.status, status));
    }
    
    if (category) {
      conditions.push(eq(cases.categoryId, category));
    }
    
    // featured字段已从schema中移除，跳过此筛选条件
    
    if (search) {
      conditions.push(
        or(
          like(cases.title, `%${search}%`),
          like(cases.description, `%${search}%`),
          like(cases.industry, `%${search}%`),
          like(cases.content, `%${search}%`)
        )
      );
    }

    // 标签筛选（如果提供了标签ID）
    if (tagIds) {
      const tagIdArray = Array.isArray(tagIds) ? tagIds : [tagIds];
      // 使用services字段来查询标签
      const tagConditions = tagIdArray.map(tagId => 
        sql`JSON_CONTAINS(${cases.services}, ${JSON.stringify([tagId])})`
      );
      conditions.push(or(...tagConditions));
    }

    const whereClause = conditions.length > 0 ? and(...conditions) : undefined;

    // 排序
    let orderBy;
    switch (sortBy) {
      case 'id':
        orderBy = sortOrder === 'desc' ? desc(cases.id) : asc(cases.id);
        break;
      case 'title':
        orderBy = sortOrder === 'desc' ? desc(cases.title) : asc(cases.title);
        break;
      case 'category':
      case 'categoryId':
        orderBy = sortOrder === 'desc' ? desc(cases.categoryId) : asc(cases.categoryId);
        break;
      case 'sort':
        orderBy = sortOrder === 'desc' ? desc(cases.sort) : asc(cases.sort);
        break;
      case 'updatedAt':
        orderBy = sortOrder === 'desc' ? desc(cases.updatedAt) : asc(cases.updatedAt);
        break;
      default:
        orderBy = sortOrder === 'desc' ? desc(cases.createdAt) : asc(cases.createdAt);
    }

    // 查询数据
    const [caseList, [{ total }]] = await Promise.all([
      db.select()
        .from(cases)
        .where(whereClause)
        .orderBy(orderBy)
        .limit(limitNum)
        .offset(offset),
      db.select({ total: count() })
        .from(cases)
        .where(whereClause)
    ]);

    // 使用映射器处理案例数据
    const processedCases = await Promise.all(
      caseList.map(async (caseItem) => {
        let serviceIds = [];
        try {
          serviceIds = JSON.parse(caseItem.services || '[]');
        } catch (error) {
          console.warn(`Invalid JSON in services field for case ${caseItem.id}:`, caseItem.services);
          serviceIds = [];
        }
        let caseTagsInfo = [];
        
        if (serviceIds.length > 0) {
          const caseTagsResult = await db.select()
            .from(tags)
            .where(inArray(tags.id, serviceIds));
          caseTagsInfo = caseTagsResult;
        }
        
        // 获取分类信息
        let categoryInfo = null;
        if (caseItem.categoryId) {
          const categoryResult = await db.select()
            .from(caseCategories)
            .where(eq(caseCategories.id, caseItem.categoryId))
            .limit(1);
          categoryInfo = categoryResult[0] || null;
        }
        
        return CaseMapper.toDTO(caseItem, caseTagsInfo, categoryInfo);
      })
    );

    const pagination = createPaginationMeta(pageNum, limitNum, total);
    
    Logger.info('获取案例列表', {
      total,
      current: pageNum,
      pageSize: limitNum,
      filters: { status, category, tags: tagIds, featured, search, sortBy, sortOrder }
    });
    
    return paginatedResponse(processedCases, pagination, '获取案例列表成功');
});

// 获取单个案例
export const getCase = asyncHandler(async ({ params, set }: Context) => {
    const { id } = params as { id: string };
    
    const caseResult = await db.select()
      .from(cases)
      .where(eq(cases.id, id))
      .limit(1);
    
    const caseItem = caseResult[0];
    
    if (!caseItem) {
      throw ApiError.notFound('案例不存在');
    }

    // 获取案例标签信息
    let serviceIds = [];
    try {
      serviceIds = JSON.parse(caseItem.services || '[]');
    } catch (error) {
      console.warn(`Invalid JSON in services field for case ${caseItem.id}:`, caseItem.services);
      serviceIds = [];
    }
    let caseTagsInfo = [];
    
    if (serviceIds.length > 0) {
      const caseTagsResult = await db.select()
        .from(tags)
        .where(inArray(tags.id, serviceIds));
      caseTagsInfo = caseTagsResult;
    }

    // 获取分类信息
    let categoryInfo = null;
    if (caseItem.categoryId) {
      const categoryResult = await db.select()
        .from(caseCategories)
        .where(eq(caseCategories.id, caseItem.categoryId))
        .limit(1);
      categoryInfo = categoryResult[0] || null;
    }

    // 使用映射器处理案例数据
    const processedCase = CaseMapper.toDTO(caseItem, caseTagsInfo, categoryInfo);

    Logger.info('获取案例详情', { caseId: id, caseTitle: caseItem.title });

    return successResponse(processedCase, '获取案例详情成功');
});

// 创建案例
export const createCase = asyncHandler(async ({ body, set, user }: AuthContext) => {
    // 权限检查：只有管理员可以创建案例
    if (!user || user.role !== 'admin') {
      throw ApiError.forbidden('权限不足，只有管理员可以创建案例');
    }
    
    const createData = body as CaseCreateDTO;

    if (!createData.title || !createData.categoryId || !createData.description || !createData.content) {
      throw ApiError.validation('案例标题、分类、描述和内容为必填项');
    }

    // 验证标签是否存在
    if (createData.tags && createData.tags.length > 0) {
      const existingTags = await db.select()
        .from(tags)
        .where(inArray(tags.id, createData.tags));
      
      if (existingTags.length !== createData.tags.length) {
        throw ApiError.validation('部分标签不存在');
      }
    }

    // 使用映射器转换数据
    const caseData = CaseMapper.fromCreateDTO(createData);
    caseData.id = nanoid();

    const [newCase] = await db.insert(cases).values(caseData).returning();

    // 获取标签信息
    let caseTagsInfo = [];
    if (createData.tags && createData.tags.length > 0) {
      const caseTagsResult = await db.select()
        .from(tags)
        .where(inArray(tags.id, createData.tags));
      caseTagsInfo = caseTagsResult;
    }

    // 获取分类信息
    let categoryInfo = null;
    if (newCase.categoryId) {
      const categoryResult = await db.select()
        .from(caseCategories)
        .where(eq(caseCategories.id, newCase.categoryId))
        .limit(1);
      categoryInfo = categoryResult[0] || null;
    }

    const processedCase = CaseMapper.toDTO(newCase, caseTagsInfo, categoryInfo);

    // 记录系统日志
    await logDatabaseOperation(
      'case',
      'create',
      `创建案例: ${createData.title}`,
      { caseId: newCase.id, categoryId: createData.categoryId, tagsCount: createData.tags?.length || 0 }
    );

    Logger.info('创建案例', { caseId: newCase.id, caseTitle: createData.title, categoryId: createData.categoryId, tagsCount: createData.tags?.length || 0 });

    return successResponse(processedCase, '案例创建成功');
});

// 更新案例
export const updateCase = asyncHandler(async ({ params, body, set, user }: AuthContext) => {
    // 权限检查：只有管理员可以更新案例
    if (!user || user.role !== 'admin') {
      throw ApiError.forbidden('权限不足，只有管理员可以更新案例');
    }
    
    const { id } = params as { id: string };
    const updateData = body as CaseUpdateDTO;

    // 检查案例是否存在
    const existingCase = await db.select()
      .from(cases)
      .where(eq(cases.id, id))
      .limit(1);

    if (existingCase.length === 0) {
      throw ApiError.notFound('案例不存在');
    }

    // 验证标签是否存在
    if (updateData.tags !== undefined && updateData.tags.length > 0) {
      const existingTags = await db.select()
        .from(tags)
        .where(inArray(tags.id, updateData.tags));
      
      if (existingTags.length !== updateData.tags.length) {
        throw ApiError.validation('部分标签不存在');
      }
    }

    // 使用映射器转换更新数据
    const dbUpdateData = CaseMapper.fromUpdateDTO(updateData);

    const [updatedCase] = await db.update(cases)
      .set(dbUpdateData)
      .where(eq(cases.id, id))
      .returning();

    // 获取标签信息
    const finalTags = updateData.tags !== undefined ? updateData.tags : JSON.parse(existingCase[0].services || '[]');
    let caseTagsInfo = [];
    if (finalTags.length > 0) {
      const caseTagsResult = await db.select()
        .from(tags)
        .where(inArray(tags.id, finalTags));
      caseTagsInfo = caseTagsResult;
    }

    // 获取分类信息
    let categoryInfo = null;
    if (updatedCase.categoryId) {
      const categoryResult = await db.select()
        .from(caseCategories)
        .where(eq(caseCategories.id, updatedCase.categoryId))
        .limit(1);
      categoryInfo = categoryResult[0] || null;
    }

    const processedCase = CaseMapper.toDTO(updatedCase, caseTagsInfo, categoryInfo);

    // 记录系统日志
    await logDatabaseOperation(
      'case',
      'update',
      `更新案例: ${existingCase[0].title}`,
      { caseId: id, updatedFields: Object.keys(dbUpdateData) }
    );

    Logger.info('更新案例', { caseId: id, updatedFields: Object.keys(dbUpdateData).length });

    return successResponse(processedCase, '案例更新成功');
});

// 删除案例
export const deleteCase = asyncHandler(async ({ params, set, user }: AuthContext) => {
    // 权限检查：只有管理员可以删除案例
    if (!user || user.role !== 'admin') {
      throw ApiError.forbidden('权限不足，只有管理员可以删除案例');
    }
    
    const { id } = params as { id: string };

    // 检查案例是否存在
    const existingCase = await db.select()
      .from(cases)
      .where(eq(cases.id, id))
      .limit(1);

    if (existingCase.length === 0) {
      throw ApiError.notFound('案例不存在');
    }

    await db.delete(cases).where(eq(cases.id, id));

    // 记录系统日志
    await logDatabaseOperation(
      'case',
      'delete',
      `删除案例: ${existingCase[0].title}`,
      { caseId: id, categoryId: existingCase[0].categoryId }
    );

    Logger.info('删除案例', { caseId: id, caseTitle: existingCase[0].title });

    return successResponse(null, '案例删除成功');
});

// 获取行业列表
export const getIndustries = asyncHandler(async ({ set }: Context) => {
    const industries = [
        { id: '1', name: '广告标识', description: '户外广告、店招标识等' },
        { id: '2', name: '商业空间', description: '商场、酒店、办公楼等' },
        { id: '3', name: '文化教育', description: '学校、博物馆、图书馆等' },
        { id: '4', name: '医疗健康', description: '医院、诊所、养老院等' },
        { id: '5', name: '交通运输', description: '机场、车站、地铁等' }
    ];
    
    Logger.info('获取行业列表', { industriesCount: industries.length });
    
    return successResponse(industries, '获取行业列表成功');
});

// 获取标签列表
export const getTags = asyncHandler(async ({ query, set }: Context) => {
    const {
      type,
      status = 'active',
      search
    } = query as any;

    const conditions = [];
    
    if (status) {
      conditions.push(eq(tags.status, status));
    }
    
    if (type) {
      conditions.push(eq(tags.type, type));
    }
    
    if (search) {
      conditions.push(
        or(
          like(tags.name, `%${search}%`),
          like(tags.type, `%${search}%`)
        )
      );
    }

    const whereClause = conditions.length > 0 ? and(...conditions) : undefined;

    const tagList = await db.select()
      .from(tags)
      .where(whereClause)
      .orderBy(asc(tags.type), asc(tags.name));

    Logger.info('获取标签列表', { tagsCount: tagList.length, filters: { type, status, search } });

    return successResponse(tagList, '获取标签列表成功');
});

// 获取单个标签
export const getTag = asyncHandler(async ({ params, set }: Context) => {
    const { id } = params as { id: string };
    
    const tagResult = await db.select()
      .from(tags)
      .where(eq(tags.id, id))
      .limit(1);
    
    const tag = tagResult[0];
    
    if (!tag) {
      throw ApiError.notFound('标签不存在');
    }

    Logger.info('获取标签详情', { tagId: id, tagName: tag.name });

    return successResponse(tag, '获取标签详情成功');
});

// 创建标签
export const createTag = asyncHandler(async ({ body, set, user }: AuthContext) => {
    // 权限检查：只有管理员可以创建标签
    if (!user || user.role !== 'admin') {
      throw ApiError.forbidden('权限不足，只有管理员可以创建标签');
    }
    
    const {
      name,
      type,
      color = '#3B82F6',
      status = 'active'
    } = body as any;

    if (!name || !type) {
      throw ApiError.validation('标签名称和类型为必填项');
    }

    // 检查标签名称是否已存在
    const existingTag = await db.select()
      .from(tags)
      .where(and(eq(tags.name, name), eq(tags.type, type)))
      .limit(1);

    if (existingTag.length > 0) {
      throw ApiError.validation('该类型下已存在同名标签');
    }

    const tagData = {
      id: nanoid(),
      name,
      type,
      color,
      status
    };

    const [newTag] = await db.insert(tags).values(tagData).returning();

    // 记录系统日志
    await logDatabaseOperation(
      'tag',
      'create',
      `创建标签: ${name}`,
      { tagId: newTag.id, type }
    );

    Logger.info('创建标签', { tagId: newTag.id, tagName: name, type });

    return successResponse(newTag, '标签创建成功');
});

// 更新标签
export const updateTag = asyncHandler(async ({ params, body, set, user }: AuthContext) => {
    // 权限检查：只有管理员可以更新标签
    if (!user || user.role !== 'admin') {
      throw ApiError.forbidden('权限不足，只有管理员可以更新标签');
    }
    
    const { id } = params as { id: string };
    const {
      name,
      type,
      color,
      status
    } = body as any;

    // 检查标签是否存在
    const existingTag = await db.select()
      .from(tags)
      .where(eq(tags.id, id))
      .limit(1);

    if (existingTag.length === 0) {
      throw ApiError.notFound('标签不存在');
    }

    const updateData: any = {};
    
    if (name !== undefined) {
      // 检查新名称是否与其他标签冲突
      const conflictTag = await db.select()
        .from(tags)
        .where(and(
          eq(tags.name, name),
          eq(tags.type, type || existingTag[0].type),
          sql`${tags.id} != ${id}`
        ))
        .limit(1);
      
      if (conflictTag.length > 0) {
        throw ApiError.validation('该类型下已存在同名标签');
      }
      
      updateData.name = name;
    }
    if (type !== undefined) updateData.type = type;
    if (color !== undefined) updateData.color = color;
    if (status !== undefined) updateData.status = status;

    const [updatedTag] = await db.update(tags)
      .set(updateData)
      .where(eq(tags.id, id))
      .returning();

    // 记录系统日志
    await logDatabaseOperation(
      'tag',
      'update',
      `更新标签: ${existingTag[0].name}`,
      { tagId: id, updatedFields: Object.keys(updateData) }
    );

    Logger.info('更新标签', { tagId: id, updatedFields: Object.keys(updateData).length });

    return successResponse(updatedTag, '标签更新成功');
});

// 删除标签
export const deleteTag = asyncHandler(async ({ params, set, user }: AuthContext) => {
    // 权限检查：只有管理员可以删除标签
    if (!user || user.role !== 'admin') {
      throw ApiError.forbidden('权限不足，只有管理员可以删除标签');
    }
    
    const { id } = params as { id: string };

    // 检查标签是否存在
    const existingTag = await db.select()
      .from(tags)
      .where(eq(tags.id, id))
      .limit(1);

    if (existingTag.length === 0) {
      throw ApiError.notFound('标签不存在');
    }

    // 检查是否有案例使用了这个标签
    const casesUsingTag = await db.select()
      .from(cases)
      .where(sql`JSON_CONTAINS(${cases.tags}, ${JSON.stringify([id])})`)
      .limit(1);

    if (casesUsingTag.length > 0) {
      throw ApiError.validation('该标签正在被案例使用，无法删除');
    }

    await db.delete(tags).where(eq(tags.id, id));

    // 记录系统日志
    await logDatabaseOperation(
      'tag',
      'delete',
      `删除标签: ${existingTag[0].name}`,
      { tagId: id, type: existingTag[0].type }
    );

    Logger.info('删除标签', { tagId: id, tagName: existingTag[0].name });

    return successResponse(null, '标签删除成功');
});